/* Yet Another Experimental Software Renderer
 *
 * Copyright (c) 2010 Pawel "Hery" Dziepak
 */

#ifndef INPUT_ASSEMBLER_H_
#define INPUT_ASSEMBLER_H_

#include "primitives.h"

#include <vector>

namespace yaesr {
	class rasterizer;
	class vertex_shader;
	class hull_shader;
	class geometry_shader;
	class domain_shader;
	class tessellator;

	class input_assembler {
	public:
		input_assembler(rasterizer *r) {
			Assert(r != NULL);

			next = r;
		}

		virtual void set_type(primitive_type) = 0;
		virtual void write_data(std::vector<vertex>&) = 0;
		
		void set_tessellator(tessellator *ts) {
			Assert(ts != NULL);

			tessell = ts;
		}

		void set_vertex_shader(vertex_shader *vs) {
			Assert(vs != NULL);

			vertex_sdr = vs;
		}

		void set_hull_shader(hull_shader *hs) {
			Assert(hs != NULL);

			hull_sdr = hs;
		}

		void set_domain_shader(domain_shader *ds) {
			Assert(ds != NULL);

			domain_sdr = ds;
		}

		void set_geometry_shader(geometry_shader *gs) {
			Assert(gs != NULL);

			geometry_sdr = gs;
		}
	protected:
		rasterizer *next;
		tessellator *tessell;
		vertex_shader *vertex_sdr;
		hull_shader *hull_sdr;
		domain_shader *domain_sdr;
		geometry_shader *geometry_sdr;
	};

	class default_ia : public input_assembler {
	public:
		default_ia(rasterizer *r) : input_assembler(r) { }

		void set_type(primitive_type tpe) {
			p_type = tpe;
		}

		void write_data(std::vector<vertex> &vbo);
	private:
		void write_points(std::vector<vertex> &vbo);
		void write_lines(std::vector<vertex> &vbo);
		void write_triangles(std::vector<vertex> &vbo);

		primitive_type p_type;
	};
}

#endif